
/*-----------------------------------------------------------------------------\
|                            The Pomodoro technique                            |
|                                                                              |
| Developer: Felipe Simões Lage Gomes Duarte                                   |
|                                                                              |
| Main Project: The Pomodoro technique                                         |
| Date: 28 / maio / 2011                                                       |
| Code: Configuration.java                                                     |
| IDE: NetBeans IDE 7.0 (Build 201104080000)                                   |
| Java: 1.6.0_24; Java HotSpot(TM) Client VM 19.1-b02                          |
|                                                                              |
\-----------------------------------------------------------------------------*/

package interfaces;

import gnu.saw.nativeutils.SAWNativeUtils;
import java.awt.*;
import java.awt.TrayIcon.MessageType;
import java.awt.event.*;
import javax.swing.*;
import util.*;

public class SystemTrayInterface {

   private final JPopupMenu popup = new JPopupMenu();
   private final SystemTray tray = SystemTray.getSystemTray();
   public static TrayIcon trayIcon = null;
   private InstanceControl cInstancia = null;
   private clock clock = null;
   public static JMenuItem clockLabel = null;
   public static JMenuItem pomodoroLabel = null;
   private JMenuItem pause = null;
   private JMenuItem timer = null;
   private JMenuItem option = null;
   private JMenuItem log = null;
   private JMenuItem sobre = null;
   private JMenuItem sair = null;
   private boolean status;

   public SystemTrayInterface() {
      //inicializa parte grafica
      createAndShowGUI();
      SAWNativeUtils.initialize();
      //Controle de Instâncias
      cInstancia = new InstanceControl(this);
      cInstancia.start();

      //start clock
      clock = new clock();
      clock.start();

      status = true;
      Log.info("Pomodoro Successfully Started");
   }

   public static void showMessage(String msg, MessageType tipo) {
      switch (tipo) {
         case INFO:
            trayIcon.displayMessage("Pomodoro", msg, TrayIcon.MessageType.INFO);
            Log.info(msg);
            break;
         case ERROR:
            trayIcon.displayMessage("Pomodoro", msg, TrayIcon.MessageType.ERROR);
            Log.error(msg);
            break;
         case WARNING:
            trayIcon.displayMessage("Pomodoro", msg, TrayIcon.MessageType.WARNING);
            Log.warn(msg);
            break;
         case NONE:
            trayIcon.displayMessage("Pomodoro", msg, TrayIcon.MessageType.NONE);
            Log.debug(msg);
            break;
      }
   }

   private void menuAction() {
      timer.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e) {
            if (!status) {
               //set timer label
               timer.setText("Status: On");
               timer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/check.png")));
               //set tray Icon
               trayIcon.setImage(new ImageIcon(getClass().getResource("/imagens/green.png")).getImage());
               trayIcon.displayMessage("Pomodoro Status", "Timer On", TrayIcon.MessageType.INFO);
               //initialize timer
               clock = new clock();
               clock.start();
               //initialize pause
               pause.setEnabled(true);
               pause.setText("Pause");
               pause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/pause.png")));
               status = true;
               Log.info("");
            } else if (status) {
               timer.setText("Status: Off");
               timer.setIcon(null);
               trayIcon.setImage(new ImageIcon(getClass().getResource("/imagens/red.png")).getImage());
               trayIcon.displayMessage("Pomodoro Status", "Timer Off", TrayIcon.MessageType.INFO);
               clock.kill();
               clockLabel.setText("00:00:00");
               pause.setEnabled(false);
               pause.setText("Pause");
               pause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/pause.png")));;
               status = false;
               //  Log.info("e-NR Robot Desligado");
            }
         }
      });

      pause.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e) {
            if (pause.getText().compareToIgnoreCase("pause") == 0) {
               clock.pause(true);
               pause.setText("Play");
               pause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/play.png")));
               trayIcon.displayMessage("Pomodoro Status", "Timer Paused", TrayIcon.MessageType.INFO);
            } else if (pause.getText().compareToIgnoreCase("play") == 0) {
               clock.pause(false);
               pause.setText("Pause");
               pause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/pause.png")));
               trayIcon.displayMessage("Pomodoro Status", "Timer Running", TrayIcon.MessageType.INFO);
            }
         }
      });

      option.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e) {
            Configuration.getInstance().setVisible(true);
         }
      });


      log.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e) {
            Log.getInstance().setVisible(true);
         }
      });

      sobre.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e) {
            new About().setVisible(true);
         }
      });


      sair.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e) {
            if (JOptionPane.showConfirmDialog(null, "Deseja realmente sair?", "Sair Pomodoro", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
               fechar();
            }
         }
      });

   }

   public void fechar() {
      if (cInstancia != null) {
         cInstancia.kill();
      }
      if (clock != null) {
         clock.kill();
      }
      tray.remove(trayIcon);
      System.exit(0);
   }

   private void createAndShowGUI() {
      //Check the SystemTray support
      if (!SystemTray.isSupported()) {
         fechar();
      }

      // Create a popup menu components
      clockLabel = new JMenuItem("00:00");
      pomodoroLabel = new JMenuItem("Pomodoro: 0");
      pause = new JMenuItem("Pause");
      pause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/pause.png")));
      timer = new JMenuItem("Status: On");
      timer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/check.png")));
      option = new JMenuItem("Configuration");
      log = new JMenuItem("Log");
      sobre = new JMenuItem("About");
      sobre.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/question.png")));
      sair = new JMenuItem("Exit");
      sair.setIcon(new javax.swing.ImageIcon(getClass().getResource("/imagens/exit.png")));

      clockLabel.setEnabled(false);
      pomodoroLabel.setEnabled(false);


      //Add components to popup menu
      popup.add(clockLabel);
      popup.add(pomodoroLabel);
      popup.add(pause);
      popup.addSeparator();
      popup.add(timer);
      popup.add(option);
      popup.add(log);
      popup.addSeparator();
      popup.add(sobre);
      popup.add(sair);


      trayIcon = new TrayIcon(new ImageIcon(getClass().getResource("/imagens/green.png")).getImage(), "Use Right Button");
      trayIcon.setImageAutoSize(true);
      trayIcon.addMouseListener(new MouseAdapter() {

         @Override
         public void mousePressed(MouseEvent e) {
            if (e.isPopupTrigger()) {
               popup.setLocation(e.getX(), e.getY());
               popup.setInvoker(popup);
               popup.setVisible(true);
            }
         }
      });

      try {
         tray.add(trayIcon);
      } catch (AWTException e) {
         JOptionPane.showMessageDialog(null, "TrayIcon could not be added.", "!!! ERROR !!!", JOptionPane.ERROR_MESSAGE);
         fechar();
      }

      trayIcon.addActionListener(new ActionListener() {

         public void actionPerformed(ActionEvent e) {
         }
      });

      menuAction();
   }

   class clock extends Thread {

      private boolean live;
      private boolean pause;
      private int hora;//Variavel que indica a hora do sistema
      private int minuto;//Variavel que indica o minuto do sistema
      private int segundo;//Variavel que indica os segundo do sistema
      private int pomodoro;
      private String horaString;//nova string horas
      private String minString;//nova string minutos
      private String segundoString;//nova string segundos
      private Estado st;

      public clock() {
         segundo = 0;
         minuto = 0;
         hora = 0;
         st = Estado.working;
      }

      @Override
      public void run() {//Metodo run da Thread
         live = true;
         try {
            while (live) {
               if (pause && live) {
                  continue;
               }
               calculoTempo();
               formatarSaida();

               if (clockLabel != null) {
                  clockLabel.setText(horaString + ":" + minString + ":" + segundoString);//Imprime o clock no Label Indicado
               }
               Thread.sleep(1000);//Dorme a thread por 1 segundo            
            }
         } catch (InterruptedException ex) {
            System.out.println("Falha clock");
         }
      }

      public void kill() {
         live = false;
      }

      public void pause(boolean situation) {
         pause = situation;
      }

      private void formatarSaida() {
         //formataçao da hora
         if (hora < 10) {//se hora for menor que 10 precisa colocar um 0 à esquerda
            horaString = "0" + hora;
         } else {
            horaString = "" + hora;
         }
         if (minuto < 10) {//se minuto for menor que 10 precisa colocar um 0 à esquerda
            minString = "0" + minuto;
         } else {
            minString = "" + minuto;
         }
         if (segundo < 10) {//se segundo for menor que 10 precisa colocar um 0 à esquerda
            segundoString = "0" + segundo;
         } else {
            segundoString = "" + segundo;
         }
      }

      private void calculoTempo() {
         //calculo do cronometro
         segundo++;
         if (segundo == 60) {
            minuto++;
            segundo = 0;
         }
         switch (st) {
            case working:
               if (minuto == Configuration.getInstance().getWt()) {
                  pomodoro++;
                  if (pomodoroLabel != null) {
                     pomodoroLabel.setText("Pomodoro: " + pomodoro);
                  }
                  st = Estado.shortInterval;
                  segundo = 0;
                  minuto = 0;
               }
               if (pomodoro == Configuration.getInstance().getP()) {
                  st = Estado.longestInterval;
                  segundo = 0;
                  minuto = 0;
               }
               if (st == Estado.shortInterval) {
                  trayIcon.displayMessage("Pomodoro",
                          "Shorter Interval Time\nInterval Time: "
                          + Configuration.getInstance().getSit() + "min.\nPomodoro: "
                          + pomodoro,
                          TrayIcon.MessageType.INFO);
                  Log.info("Shorter Interval Time\nInterval Time: "
                          + Configuration.getInstance().getSit() + "min.\nPomodoro: "
                          + pomodoro);

                  SAWNativeUtils.beep(2000, 2000, true);
                  java.awt.Toolkit.getDefaultToolkit().beep();
                  System.out.println("\007");

               } else if (st == Estado.shortInterval) {
                  trayIcon.displayMessage("Pomodoro", "Longest Interval Time", TrayIcon.MessageType.INFO);
                  Toolkit.getDefaultToolkit().beep();
               }
               break;
            case shortInterval:
               if (minuto == Configuration.getInstance().getSit()) {
                  st = Estado.working;
                  segundo = 0;
                  minuto = 0;
               }
               break;
            case longestInterval:
               if (minuto == Configuration.getInstance().getLit()) {
                  st = Estado.working;
                  segundo = 0;
                  minuto = 0;
                  pomodoro = 0;
               }
               break;
         }
      }
   }

   private enum Estado {

      working, shortInterval, longestInterval;
   }
}